package com.chenjie.drools.drl;

import java.lang.reflect.Modifier;
import java.net.URL;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.springframework.boot.system.ApplicationHome;
import org.springframework.util.CollectionUtils; 
import com.chenjie.drools.dao.primary.model.Property;

import javassist.CannotCompileException;
import javassist.ClassPool;
import javassist.CtClass;
import javassist.CtField;
import javassist.NotFoundException;
import lombok.Data;

@Data
public class BeanManager {
	//private static String PATH = BeanManager.class.getResource("/").getPath();

	private static String PATH = "";
	static {
		ApplicationHome ah = new ApplicationHome(); 
		PATH = ah.getDir().toString();
	}
	
	private static BeanManager instance;

	private Map<String, Class> loadedDynamicClass = new HashMap<String, Class>();

	private ClassPool pool = ClassPool.getDefault();

	public static BeanManager getInstance() {
		if (instance == null) {
			instance = new BeanManager();
		}
		return instance;
	}

	public void create(String clazzName, List<Property> properties) {
		try {
			remove(clazzName);
			CtClass ct = pool.makeClass(clazzName);   
			setPropery(ct, properties);
			loadedDynamicClass.put(clazzName, ct.toClass());
			ct.writeFile(PATH);
			//Class.forName(clazzName);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	public void setPropery(CtClass ctClass, List<Property> properties) {
		if (ctClass != null && CollectionUtils.isEmpty(properties)) {
			return;
		} 
		try {
			for (Property property : properties) {
				CtField ctf = new CtField(pool.get("java.lang." + property.getDataType()), property.getName(), ctClass);
				ctf.setModifiers(Modifier.PUBLIC);
				ctClass.addField(ctf);
			} 
		} catch (CannotCompileException | NotFoundException e) {
			e.printStackTrace();
		}

	} 

	public void remove(String clazzName) {
		try {
			Class clazz = loadedDynamicClass.get(clazzName);
			if (clazz != null) {
				CtClass ct = pool.get(clazzName);
				ct.detach();
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	public Boolean isExist(String clazz) {
		Boolean exist = true;
		try {
			CtClass ct = pool.get(clazz);
			URL url = ct.getURL();
			if (url == null) {
				exist = false;
			}
		} catch (NotFoundException e) {
			e.printStackTrace();
			exist = false;
		}
		return exist;
	}

	public static void main(String[] args) throws InstantiationException, IllegalAccessException {
		BeanManager beanManager = BeanManager.getInstance();
		String clazz = "quality.student";  
		
		List<Property> properties = new ArrayList<Property>();
	    properties.add(new Property("name", "String"));
	    properties.add(new Property("age", "Integer"));
	    beanManager.create(clazz, properties);
	    
	    Class<?> cladd = beanManager.loadedDynamicClass.get(clazz); 
		Object object = cladd.newInstance();
	    System.out.println(object);
	}

}
